package section2_7;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by Hyman on 2017/6/2.
 *
 * 打印队列类，模拟一个打印队列事件
 */
public class PrintQueue {

    /**
     * 用于控制队列访问的锁
     *
     * ReentrantLock和ReentrantReadWriteLock类的构造器都含有一个布尔参数fair，
     * 它允许你控制这两个类的行为。默认fair的值是false,它称为非公平模式（Non-Fair Mode)。
     * 在非公平模式下，当有很多线程在等待锁（ReentrantLock和ReentrantReadWriteLock）时，锁将选择它们中的一个来访问临界区,这个选择是没有任何约束的。
     * 如果fail的值是true, 则称为公平模式（Fair Mode)。
     * 在公平模式下，当有很多线程在等待锁（ReentrantLock和ReentrantReadWriteLock）时，锁将选择它们中的一个来访问临界区，而且选择的是等待时间最长的。
     * 这两种模式只适用于lock()和unlock()方法。而Lock接口的tryLock〇方法没有将线程置于休眠，fair属性并不影响这个方法。
     */
    private final Lock queueLock = new ReentrantLock(true);

    /**
     * 打印一个文档
     *
     * @param object 要打印的文档对象
     */
    public void printJob(Object object) {
        queueLock.lock(); // 上锁
        try {
            long duration = (long) (Math.random() * 10000);
            System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(), (duration / 1000));
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            queueLock.unlock(); // 解锁
        }

        queueLock.lock();
        try {
            long duration = (long) (Math.random() * 10000);
            System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(), (duration / 1000));
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            queueLock.unlock(); // 解锁
        }
    }
}
